package io.zhengsh.redis.controller;

import io.zhengsh.redis.annotation.MultiCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;

    @MultiCache(key = "'order.seckill:'+ #orderDto.skuNo", timeOut = 10000, op = "delete")
    @GetMapping("/createOrder")
    public OrderDto createOrder(@Validated OrderDto orderDto) {
        //1.参数教研
        if (orderDto.getQuantity() == null || orderDto.getQuantity() < 1) {
            throw new RuntimeException("unknown error");
        }
        String key = String.format("order.stock:%s", orderDto.getSkuNo());
        Serializable serializable = redisTemplate.opsForValue().decrement(key, orderDto.getQuantity());
        if (serializable == null) {
            throw new RuntimeException("unknown error");
        }
        Integer stock = Optional.of(Integer.parseInt(String.valueOf(redisTemplate.opsForValue().get(key)))).orElse(0);
        OrderDto resultDto = new OrderDto();
        resultDto.setSkuNo(orderDto.getSkuNo());
        if (stock >= 0) {
            resultDto.setQuantity(orderDto.quantity);
        } else {
            resultDto.setQuantity(-1);
        }
        return resultDto;
    }

    @MultiCache(key = "'order.seckill:'+ #skuNo", timeOut = 10000)
    @GetMapping("/querySku/{skuNo}")
    public List<SkuDto> querySku(@Validated @PathVariable(value = "skuNo") @NotBlank String skuNo) {
        Serializable serializable = redisTemplate.opsForValue().get(String.format("order.stock:%s", skuNo));
        SkuDto skuDto1 = new SkuDto(skuNo, Optional.of(Integer.parseInt(String.valueOf(serializable))).orElse(0));
        return Arrays.asList(skuDto1, new SkuDto("SKU00008", -1));
    }

    static class SkuDto {
        String skuNo;

        Integer quantity;

        public SkuDto(String skuNo, Integer quantity) {
            this.skuNo = skuNo;
            this.quantity = quantity;
        }

        public String getSkuNo() {
            return skuNo;
        }

        public void setSkuNo(String skuNo) {
            this.skuNo = skuNo;
        }

        public Integer getQuantity() {
            return quantity;
        }

        public void setQuantity(Integer quantity) {
            this.quantity = quantity;
        }
    }

    static class OrderDto {
        @NotBlank
        String skuNo;

        @NotNull
        @Min(0)
        @Max(100)
        Integer quantity;

        public String getSkuNo() {
            return skuNo;
        }

        public void setSkuNo(String skuNo) {
            this.skuNo = skuNo;
        }

        public Integer getQuantity() {
            return quantity;
        }

        public void setQuantity(Integer quantity) {
            this.quantity = quantity;
        }
    }

}
